/**
 *  @file FileBody.cpp
 */
#include "IHttpBody.h"
#include "../../../common/CppMemPool.h"
#include "../../../io/FileStream.h"

using namespace cppflib::collections;
using namespace cppflib::io;

namespace cppflib
{

namespace net
{

namespace http
{

namespace message
{


FileBody::FileBody()
{
}

FileBody::FileBody(pcwstr_t filePath)
{
   this->filePath = filePath;
   SetCurReadPos(0);
}

FileBody::~FileBody()
{
   CloseFile();
}

void FileBody::OpenFile()
{
   if (!pStream) {
      pStream = new FileStream(filePath, FileStream::FA_READONLY);
      cppmempool::Retain(pStream);
   }
}

void FileBody::CloseFile()
{
   if (pStream) {
      cppmempool::Release(pStream);
      pStream = NULL;
   }
}

u64_t FileBody::GetContentLength(void)
{
   OpenFile();
   SetContentLength(pStream->GetFileSize());
   return IHttpBody::GetContentLength();
}

int FileBody::Read(collections::ArrayByte &buffer)
{
   return Read(buffer, 0, static_cast<int>(buffer.GetSize()));
}

int FileBody::Read(collections::ArrayByte &buffer, int offset, int count)
{
   OpenFile();

   if (GetContentLength() - GetCurReadPos() == 0)
      return 0;

   int ret = pStream->Read(buffer, offset, count);
   if (ret > 0)
      AdvanceReadPos(ret);
   return ret;
}

int FileBody::Read()
{
   OpenFile();

   if (GetContentLength() - GetCurReadPos() == 0)
     return -1;

   int ret = pStream->Read();
   if (ret >= 0)
      AdvanceReadPos(1);
   return ret;
}

void FileBody::Close()
{
   CloseFile();
}

} // end of namespace message

} // end of namespace http

} // end of namespace net

} // end of namespace cppflib

